package edu.ccut.saturn.studio.logic.model;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.eclipse.gef.ui.parts.GraphicalEditorWithFlyoutPalette;
import org.w3c.dom.Document;

import edu.ccut.saturn.studio.logic.contextaction.IEditorMultiPage;
import edu.ccut.saturn.studio.logic.model.saturn.SaturnInformationNode;
import edu.ccut.saturn.studio.logic.model.saturn.SaturnStartNode;

public class ShapesDiagram extends BasicShape {

	private static final long serialVersionUID = 238078924439643564L;

	private IEditorMultiPage editors;

	public static final String CHILD_ADDED_PROP = "ShapesDiagram.ChildAdded";

	public static final String CHILD_REMOVED_PROP = "ShapesDiagram.ChildRemoved";

	private GraphicalEditorWithFlyoutPalette editor;

	private Document document;

	private Set<Shape> modifyShapes = new HashSet<Shape>();

	private List<Shape> shapes = new ArrayList<Shape>();

	public ShapesDiagram(GraphicalEditorWithFlyoutPalette editor, Document document) {
		super();
		this.editor = editor;
		this.document = document;
	}

	public boolean addShape(Shape shape) {
		if (shapes != null) {
			if (shape instanceof SaturnStartNode) {
				for (int i = 0; i < shapes.size(); i++) {
					if ((shapes.get(i) instanceof SaturnStartNode)) {
						return false;
					}
				}
			} else if (shape instanceof SaturnInformationNode) {
				for (int i = 0; i < shapes.size(); i++) {
					if ((shapes.get(i) instanceof SaturnInformationNode)) {
						return false;
					}
				}
			}
			
			shape.setParent(this);
			shape.setDocument(document);
			shape.refresh();
			shapes.add(shape);
			firePropertyChange(CHILD_ADDED_PROP, null, shape);
			return true;
		}
		
		return false;
	}

	public void addShapes(List<Shape> shapes) {
		if (shapes != null) {
			for (Shape shape : shapes) {
				this.addShape(shape);
			}
		}
	}

	public void removeModifyShapes() {
		this.modifyShapes.removeAll(this.modifyShapes);
	}

	public boolean modifyShape(Shape shape) {
		return this.modifyShapes.add(shape);
	}

	public boolean removeShape(Shape shape) {
		if (shape != null) {
			shape.clear();
			
			shapes.remove(shape);
			modifyShapes.remove(shape);
			firePropertyChange(CHILD_REMOVED_PROP, null, shape);
			return true;
		}
		
		return false;
	}

	public List<Shape> getShapes() {
		return shapes;
	}

	public String getNextValidShapeId() {
		int maxId = 0;

		for (Shape shape : shapes) {
			try {
				int shapeId = Integer.parseInt(shape.getId());

				if (maxId < shapeId) {
					maxId = shapeId;
				}
			} catch (NumberFormatException e) {
				e.printStackTrace();
			}
		}

		return ++maxId + "";
	}

	public GraphicalEditorWithFlyoutPalette getEditor() {
		return editor;
	}

	public void setEditor(GraphicalEditorWithFlyoutPalette editor) {
		this.editor = editor;
	}

	public IEditorMultiPage getEditors() {
		return editors;
	}

	public void setEditors(IEditorMultiPage editors) {
		this.editors = editors;
	}

	public Document getDoc() {
		return document;
	}

	public void setDoc(Document doc) {
		this.document = doc;
	}

	public Set<Shape> getModifyShapes() {
		return modifyShapes;
	}

	public void setModifyShapes(Set<Shape> modifyShapes) {
		this.modifyShapes = modifyShapes;
	}
}